package com.nubaseg.parser;

import java.util.*;

/**
 * Created with IntelliJ IDEA.
 * User: Nubaseg
 * Date: 20.10.13
 * Time: 0:20
 */
public class ArithmeticParser {

    private static final String PLUS = "+";
    private static final String MINUS = "-";
    private static final String MUL = "*";
    private static final String DIV = "/";
    private static final String LEFT_BRACKET = "(";
    private static final String RIGHT_BRACKET = ")";

    private static final Set<String> NONVALUES = new HashSet<String>(
            Arrays.asList(PLUS, MINUS, MUL, DIV, LEFT_BRACKET, RIGHT_BRACKET));

    private static final Set<String> OPERATORS2 = new HashSet<String>(
            Arrays.asList(PLUS, MINUS));

    private static final Set<String> OPERATORS3 = new HashSet<String>(
            Arrays.asList(MUL, DIV));

    private static getPriority(String )

    public enum Associative {LEFT, RIGHT};

    public static boolean isOperator(String token) {
        if (PLUS.equals(token) || MINUS.equals(token) || MUL.equals(token) || DIV.equals(token))
            return true;
        return false;
    }

    public static double RPNtoDouble(String[] tokens) {
        Stack<String> stack = new Stack<String>();
        for (String token : tokens) {
            if (!isOperator(token)) {
                stack.push(token);
            } else {
                Double d2 = Double.valueOf(stack.pop());
                Double d1 = Double.valueOf(stack.pop());
                Double result = token.compareTo(PLUS) == 0 ? d1 + d2 :
                        token.compareTo(MINUS) == 0 ? d1 - d2 :
                                token.compareTo(MUL) == 0 ? d1 * d2 :
                                        d1 / d2;
                stack.push(String.valueOf(result));
            }
        }
        return Double.valueOf(stack.pop());
    }

    private static boolean isAssociative(String operator)

    public static String[] infixToRPN(String[] inputTokens) {
        ArrayList<String> out = new ArrayList<String>();
        Stack<String> stack = new Stack<String>();

        for (String token : inputTokens) {
            if (isOperator(token)) {
                // While stack not empty AND stack top element
                // is an operator
                while (!stack.empty() && isOperator(stack.peek())) {
                    if ((isAssociative(token, LEFT_ASSOC) &&
                            cmpPrecedence(token, stack.peek()) <= 0) ||
                            (isAssociative(token, RIGHT_ASSOC) &&
                                    cmpPrecedence(token, stack.peek()) < 0)) {
                        out.add(stack.pop());
                        continue;
                    }
                    break;
                }
                // Push the new operator on the stack
                stack.push(token);
            } else if (token.equals(LEFT_BRACKET)) {
                stack.push(token);  //
            } else if (token.equals(RIGHT_BRACKET)) {
                while (!stack.empty() && !stack.peek().equals("(")) {
                    out.add(stack.pop());
                }
                stack.pop();
            } else {
                out.add(token);
            }
        }
        while (!stack.empty()) {
            out.add(stack.pop());
        }
        String[] output = new String[out.size()];
        return out.toArray(output);
    }
}
